﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.IO;
using System.Threading;

namespace OmauraOledTest
{
    public partial class Form1 : Form
    {

        public System.IO.Ports.SerialPort serialPort1 = new System.IO.Ports.SerialPort();

        private Bitmap scrollingText;
        private int scrollingTextPosition = 0;
        private int scrollingTextHeight = 0;
        private int scrollingTextWidth = 0;
        private int scrollingPosX = 0;
        private int scrollingPosY = 0;
        private bool scrollingRightToLeft = true;

        public Form1()
        {
            InitializeComponent();

            label2.Text = "";
            //-- init the serial port
            serialPort1.ReadTimeout = 50;
            serialPort1.NewLine = "\n";
        }

        private void button1_Click(object sender, EventArgs e)
        {
            bool deviceFound = false;
            //-- Launch Connection
            //comboBox2.Items.Add(System.IO.Ports.SerialPort.GetPortNames());
            foreach (string Port in System.IO.Ports.SerialPort.GetPortNames())
                comboBox1.Items.Add(Port);

            textBox1.Text = "";

            for (int i = 0; i < comboBox1.Items.Count; i++)
            {
                string retString;
                comboBox1.SelectedIndex = i;
                serialPort1.PortName = comboBox1.Text;
                serialPort1.BaudRate = 500000;//(int)numericUpDown1.Value;
                try
                {
                    textBox1.Text += "Opening port " + serialPort1.PortName + "\r\n";
                    serialPort1.Open();
                    if (serialPort1.IsOpen)
                    {
                        textBox1.Text += "Opened port " + serialPort1.PortName + "\r\n";
                        byte[] buffer = new byte[2];
                        buffer[0] = 0x70; // Start code
                        buffer[1] = 0x71; // Recognition code
                        textBox1.Text += "Send OLED recognition code" + "\r\n";
                        serialPort1.Write(buffer, 0, 2);
                        string tempString = serialPort1.ReadLine();
                        textBox1.Text += "Read from port " + serialPort1.PortName + ": " + tempString + "\r\n";
                        if (tempString.Length > 1)
                        {
                            if (tempString.Substring(0, tempString.IndexOf(" ")) == "OLED")
                            {
                                deviceFound = true;
                                textBox1.Text += "Found OLED @ port " + serialPort1.PortName + "\r\n";
                            }
                            else
                            {
                                textBox1.Text += "No OLED found @ " + serialPort1.PortName + "\r\n";
                            }

                        }
                        else
                        {
                            textBox1.Text += "No string read from OLED; no OLED found" + "\r\n";
                        }

                    }
                }
                catch (Exception ex)
                {
                    textBox1.Text += "Exception occurred; no OLED found" + "\r\n";
                }
                if (deviceFound)
                    i = comboBox1.Items.Count;
                else
                {
                    textBox1.Text += "Closing port " + serialPort1.PortName + "\r\n";
                    serialPort1.Close();
                }
            }
            if (deviceFound)
            {
                label2.Text = "Device found @ serial port " + serialPort1.PortName;
            }
            else
            {
                label2.Text = "Device not found";
            }

            if (deviceFound && serialPort1.IsOpen)
            {
                byte[] buffer = new byte[2];
                buffer[0] = 0x70; // Start code
                buffer[1] = 0x80; // Erase code
                serialPort1.Write(buffer, 0, 2);
            
                System.Threading.Thread.Sleep(100);

                sendBitmapText("OmauraOLEDTest", 0, 0, false, false);
            }



            if (serialPort1.IsOpen)
            {
                serialPort1.Close();
            }
        }

        public void sendBitmapText(string strToSend, int posx, int posy, bool erase, bool canScroll)
        {
            byte part1, part2;
            Graphics g;
            Size textSize = System.Windows.Forms.TextRenderer.MeasureText(strToSend, new Font("Tahoma", 12));
            if ((textSize.Width < 256 && textSize.Height < 64) &&
                (textSize.Width != 0 && textSize.Height != 0))
            {
                Bitmap bitmap = new Bitmap(256, 64);
                g = Graphics.FromImage(bitmap);
                System.Windows.Forms.TextRenderer.DrawText(g, strToSend, new Font("Tahoma", 12), Point.Empty, Color.White, Color.Black);
                // Send the data contained in the bitmap to the serial port thanks to the getPixel method
                if (serialPort1.IsOpen)
                {
                    int i, j;
                    int widthTemp;
                    if (erase)
                        widthTemp = 128;
                    else
                    {
                        if (textSize.Width >= 256)
                            widthTemp = 128;
                        else
                        {
                            widthTemp = textSize.Width / 2;
                            if (widthTemp * 2 < widthTemp) widthTemp++;
                        }
                    }

                    int nbBytes = 8 + (textSize.Height * widthTemp);
                    byte[] buffer = new byte[nbBytes];
                    buffer[0] = 0x70; // Start code
                    buffer[1] = 0x82; // Icon code
                    buffer[2] = (byte)posx; // x (0 - 127)
                    buffer[3] = (byte)posy; // y (0 - 63)
                    buffer[4] = (byte)widthTemp; // Width
                    buffer[5] = (byte)textSize.Height; // Height
                    buffer[6] = 1; // vertical

                    for (j = 0; j < textSize.Height; j++)
                    {
                        for (i = 0; i < widthTemp; i++)
                        {
                            part1 = convertColor(System.Drawing.ColorTranslator.ToWin32(bitmap.GetPixel(i * 2 + 1, (textSize.Height - j))));
                            if (i + 1 < textSize.Width)
                                part2 = convertColor(System.Drawing.ColorTranslator.ToWin32(bitmap.GetPixel(i * 2, (textSize.Height - j))));
                            else
                                part2 = 0;
                            buffer[7 + i + j * widthTemp] = (byte)((byte)(part1 & 0xF0) + (byte)(part2 >> 4));
                        }
                    }
                    buffer[nbBytes - 1] = 0;

                    serialPort1.Write(buffer, 0, nbBytes);

                    /*
                    byte[] buffer = new byte[nbBytes];
                    buffer[0] = 0x70; // Start code
                    buffer[1] = 0x82; // Icon code
                    buffer[2] = (byte)posx; // x (0 - 127)
                    buffer[3] = (byte)posy; // y (0 - 63)
                    buffer[4] = (byte)widthTemp; // Width
                    buffer[5] = (byte)textSize.Height; // Height
                    buffer[6] = 1; // vertical
                    buffer[7] = 16; // nbColors

                    for (j = 0; j < textSize.Height; j++)
                    {
                        for (i = 0; i < widthTemp; i++)
                        {
                            part1 = convertColor(System.Drawing.ColorTranslator.ToWin32(bitmap.GetPixel(i * 2 + 1, (textSize.Height - j))));
                            if (i + 1 < textSize.Width)
                                part2 = convertColor(System.Drawing.ColorTranslator.ToWin32(bitmap.GetPixel(i * 2, (textSize.Height - j))));
                            else
                                part2 = 0;
                            buffer[8 + i + j * widthTemp] = (byte)((byte)(part1 & 0xF0) + (byte)(part2 >> 4));
                        }
                    }
                    parent.serialPort1.Write(buffer, 0, nbBytes);
                    */
                }
            }
            else if ((textSize.Width < 2048 && textSize.Height < 64) &&
                (textSize.Width != 0 && textSize.Height != 0) && canScroll)
            {
                scrollingText = new Bitmap(2048, 64);
                g = Graphics.FromImage(scrollingText);
                System.Windows.Forms.TextRenderer.DrawText(g, strToSend, new Font("Tahoma", 12), Point.Empty, Color.White, Color.Black);
                int widthTemp = 0;
                // Send the data contained in the bitmap to the serial port thanks to the getPixel method
                if (serialPort1.IsOpen)
                {
                    int i, j;
                    widthTemp = textSize.Width / 2;
                    if (widthTemp * 2 < widthTemp)
                        widthTemp++;
                    int nbBytes = 8 + (textSize.Height * widthTemp);

                    byte[] buffer = new byte[nbBytes];
                    buffer[0] = 0x70; // Start code
                    buffer[1] = 0x82; // Icon code
                    buffer[2] = (byte)posx; // x (0 - 127)
                    buffer[3] = (byte)posy; // y (0 - 63)
                    buffer[4] = (byte)widthTemp; // Width
                    buffer[5] = (byte)textSize.Height; // Height
                    buffer[6] = 1; // vertical
                    buffer[7] = 16; // nbColors

                    for (j = 0; j < textSize.Height; j++)
                    {
                        for (i = 0; i < 128; i++)
                        {
                            part1 = convertColor(System.Drawing.ColorTranslator.ToWin32(scrollingText.GetPixel(i * 2 + 1, (textSize.Height - j))));
                            if (i + 1 < textSize.Width)
                                part2 = convertColor(System.Drawing.ColorTranslator.ToWin32(scrollingText.GetPixel(i * 2, (textSize.Height - j))));
                            else
                                part2 = 0;
                            buffer[7 + i + j * widthTemp] = (byte)((byte)(part1 & 0xF0) + (byte)(part2 >> 4));
                        }
                    }
                    buffer[nbBytes - 1] = 0;

                    serialPort1.Write(buffer, 0, nbBytes);

                    /*
                    byte[] buffer = new byte[nbBytes];
                    buffer[0] = 0x70; // Start code
                    buffer[1] = 0x82; // Icon code
                    buffer[2] = (byte)posx; // x (0 - 127)
                    buffer[3] = (byte)posy; // y (0 - 63)
                    buffer[4] = (byte)widthTemp; // Width
                    buffer[5] = (byte)textSize.Height; // Height
                    buffer[6] = 1; // vertical
                    buffer[7] = 16; // nbColors

                    for (j = 0; j < textSize.Height; j++)
                    {
                        for (i = 0; i < 128; i++)
                        {
                            part1 = convertColor(System.Drawing.ColorTranslator.ToWin32(scrollingText.GetPixel(i * 2 + 1, (textSize.Height - j))));
                            if (i + 1 < textSize.Width)
                                part2 = convertColor(System.Drawing.ColorTranslator.ToWin32(scrollingText.GetPixel(i * 2, (textSize.Height - j))));
                            else
                                part2 = 0;
                            buffer[8 + i + j * widthTemp] = (byte)((byte)(part1 & 0xF0) + (byte)(part2 >> 4));
                        }
                    }
                    parent.serialPort1.Write(buffer, 0, nbBytes);
                    */
                }
                scrollingTextPosition = 0;
                scrollingRightToLeft = true;
                scrollingPosX = posx;
                scrollingPosY = posy;
                scrollingTextHeight = textSize.Height;
                scrollingTextWidth = widthTemp;
            }
            else
            {
                //Log.Write("Texte trop grand");
            }
        }

        private byte convertColor(int colorWin32)
        {
            int red = colorWin32 & 255;
            int green = (colorWin32 & 65280) >> 8;
            int blue = (colorWin32 & 16711680) >> 16;
            int mean = (red + green + blue) / 3;
            return (byte)mean;//(mean / 3 + 170);
        }

        private void Form1_Load(object sender, EventArgs e)
        {
     
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            if (!serialPort1.IsOpen)
            {
                serialPort1.Open();
                byte[] buffer = new byte[2];
                buffer[0] = 0x70; // Start code
                buffer[1] = 0x80; // Erase code
                serialPort1.Write(buffer, 0, 2);

                System.Threading.Thread.Sleep(100);
                serialPort1.Close();
            }
        }
    }
}
